package panel.role.xmlgenerate;

import com.plealog.genericapp.api.EZEnvironment;
import net.miginfocom.swing.MigLayout;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.JXTextArea;
import org.jdesktop.swingx.JXTextField;
import session.BaseSession;
import session.RoleSession;

import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 根据贴图后缀生成_yabber-tpf.xml文件
 */
public class XmlGeneratePanel extends JPanel {
	private JButton okButton = new JButton("生成_yabber-tpf.xml");
	private JTextField savePathField = new JXTextField("dds文件路径");
	private JTextField filenameField = new JXTextField("xml文件名（不加后缀）");
	private JButton fileChooserButton = new JButton("选择");
	private JFileChooser fileChooser = new JFileChooser();
	private JXTable table;
	private DefaultTableModel tableModel;
	private static final String[] TABLE_HEADER = new String[]{"format", "图片后缀"};

	public XmlGeneratePanel() {
		setLayout(new MigLayout("wrap 2", "grow"));

		initLayout();
		initListener();
	}

	private void initLayout() {
		JLabel ddsLabel = new JLabel("dds文件目录");
		JTextArea helpTextArea = new JXTextArea("    一般情况0x00用于其他，0x01用于漫反射，0x67用于高光，0x6B用于法线");
		helpTextArea.setEditable(false);
		helpTextArea.setFocusable(false);

		savePathField.setColumns(30);
		savePathField.setText(RoleSession.DDS_PATH);
		JLabel filenameLabel = new JLabel("打包后文件名（不加后缀）");
		filenameField.setToolTipText("打包后生成的文件名，例如XXX.tpf，填写的时候不要加后缀");
		filenameField.setColumns(30);
		filenameField.setText(RoleSession.XML_FILENAME);

		tableModel = new DefaultTableModel();
		table = new JXTable(tableModel);
		table.setSortable(false);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		// 填充数据
		String[][] data = new String[RoleSession.TEXTURE_XML_ITEMS.size()][2];
		for (int i = 0; i < RoleSession.TEXTURE_XML_ITEMS.size(); i++) {
			data[i] = RoleSession.TEXTURE_XML_ITEMS.get(i);
		}
		tableModel.setDataVector(data, TABLE_HEADER);

		JScrollPane scrollPane = new JScrollPane(table);
		scrollPane.setBorder(null);
		add(scrollPane, "span, center,growx");

		add(ddsLabel, "span, split 3");
		add(savePathField);
		add(fileChooserButton);
		add(filenameLabel, "span, split 2");
		add(filenameField);
		add(okButton, "span, center");
		JScrollPane scrollPane1 = new JScrollPane(helpTextArea);
		scrollPane1.setBorder(null);
		add(scrollPane1,"span, growx, h 100::");
	}

	private void initListener() {
		tableModel.addTableModelListener(e -> {
			if (e.getType() == TableModelEvent.UPDATE && e.getFirstRow() != -1) {
				String[] tuple = RoleSession.TEXTURE_XML_ITEMS.get(e.getFirstRow());
				if (e.getColumn() == 0) tuple[0] = (String) tableModel.getValueAt(e.getFirstRow(), e.getColumn());
				else tuple[1] = (String) tableModel.getValueAt(e.getFirstRow(), e.getColumn());
			}
		});

		fileChooser.setCurrentDirectory(new File("."));
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		fileChooserButton.addActionListener(e -> {
			if (fileChooser.showOpenDialog(EZEnvironment.getParentFrame()) == JFileChooser.APPROVE_OPTION) {
				savePathField.setText(fileChooser.getSelectedFile().getAbsolutePath());
			}
		});

		addAncestorListener(new AncestorListener() {
			@Override
			public void ancestorAdded(AncestorEvent event) {
				savePathField.setText(RoleSession.DDS_PATH);
				filenameField.setText(RoleSession.XML_FILENAME);
			}

			@Override
			public void ancestorRemoved(AncestorEvent event) {
				BaseSession.setVal(RoleSession.class, "DDS_PATH", savePathField.getText());
				BaseSession.setVal(RoleSession.class, "XML_FILENAME", filenameField.getText());
			}

			@Override
			public void ancestorMoved(AncestorEvent event) {

			}
		});

		okButton.addActionListener(e -> {
			String msg = checkData();
			if (msg != null) {
				JOptionPane.showConfirmDialog(EZEnvironment.getParentFrame(), msg, "提示", JOptionPane.DEFAULT_OPTION);
				return;
			}

			String name = "_yabber-tpf.xml";
			String dir = savePathField.getText().replaceAll("/", "\\\\");
			String filePath = dir + (dir.endsWith("\\") ? name : "\\" + name);
			File file = new File(filePath);

			BufferedWriter bw;
			try {
				bw = new BufferedWriter(new FileWriter(file, StandardCharsets.UTF_8));
				bw.append(generateXmlInfo(new File(dir)));
				bw.close();
			} catch (IOException ex) {
				JOptionPane.showConfirmDialog(EZEnvironment.getParentFrame(), "文件保存失败，" + ex.getMessage(), "提示", JOptionPane.DEFAULT_OPTION);
			}
			JOptionPane.showConfirmDialog(EZEnvironment.getParentFrame(), "_yabber-tpf.xml文件生成完毕", "提示", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE);
		});
	}

	private String checkData() {
		if (!new File(savePathField.getText()).isDirectory())
			return "保存路径不合法";
		if (filenameField.getText().equals(""))
			return "文件名不能为空";
		return null;
	}

	private StringBuilder generateXmlInfo(File dir) throws IOException {
		StringBuilder builder = new StringBuilder();
		String filename = filenameField.getText();
		if (!filename.endsWith(".tpf"))
			filename = filename + ".tpf";

		builder.append("<tpf>\n")
				.append("<filename>").append(filename).append("</filename>\n")
				.append("<compression>None</compression>\n")
				.append("<encoding>0x01</encoding>\n")
				.append("<flag2>0x03</flag2>\n")
				.append("<textures>\n");

		String[] names = dir.list((dir1, name) -> name.endsWith(".dds"));
		if (names != null) {
			HashMap<Set<String>, String> map = new HashMap<>();
			RoleSession.TEXTURE_XML_ITEMS.forEach(tuple -> {
				HashSet<String> suffixSet = new HashSet<>(List.of(tuple[1].split(",")));
				suffixSet.remove("");
				map.put(suffixSet, tuple[0]);
			});

			Arrays.stream(names).forEach(name -> {
				name = name.substring(0, name.length() - 4);
				Set<String> set = Arrays.stream(name.split("_")).filter(s -> !s.equals("")).collect(Collectors.toSet());
				for (Set<String> suffixSet : map.keySet()) {
					// 多对多的关系，只要有交集，这里就算符合
					Set<String> tmpSet = new HashSet<>(set); //执行retainAll前拷贝一份
					tmpSet.retainAll(suffixSet);
					if (tmpSet.size() != 0) {
						builder.append("<texture>\n")
								.append("<name>").append(name).append("</name>\n")
								.append("<format>").append(map.get(suffixSet)).append("</format>\n")
								.append("<flags1>0x00</flags1>\n")
								.append("<flags2>0x00000000</flags2>\n")
								.append("</texture>\n");
					}
				}
			});
		}

		builder.append("</textures>\n" +
		               "</tpf>");

		return builder;
	}

}
